﻿/************************************************************************

   Extended Silverlight Toolkit

   Copyright (C) 2010-2012 Xceed Software Inc.

   This program is provided to you under the terms of the Microsoft Public
   License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license

   Please purchase a commercial version of this toolkit if you are using
   it in a commercial product. The commercial versions support the project,
   and also include more features for each control, priority support,
   source code, updates, removed watermark, and a proprietary license.

   Visit http://xceed.com and follow @datagrid on Twitter.

  **********************************************************************/

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace Xceed.Silverlight.Data
{
  public class DataSourceChangedEventArgs : EventArgs
  {
    #region Constructors

    public DataSourceChangedEventArgs( DataSourceChangedAction action )
    {
      if( action != DataSourceChangedAction.Reset )
        throw new ArgumentException( "Only the Reset action is supported by this constructor.", "action" );

      this.Initialize( action, null, null, null );
    }

    public DataSourceChangedEventArgs( 
      DataSourceChangedAction action, 
      IEnumerable<object> newItems,
      IEnumerable<object> oldItems )
    {
      if( action == DataSourceChangedAction.Add && newItems == null )
        throw new ArgumentException( "newItems must be specified when the Add action is specified.", "newItems" );

      if( action == DataSourceChangedAction.Remove && oldItems == null )
        throw new ArgumentException( "oldItems must be specified when the Remove action is specified.", "oldItems" );

      if( action == DataSourceChangedAction.Replace )
      {
        if( newItems == null )
          throw new ArgumentException( "newItems must be specified when the Replace action is specified.", "newItems" );

        if( oldItems == null )
          throw new ArgumentException( "oldItems must be specified when the Replace action is specified.", "oldItems" );
      }

      this.Initialize( action, newItems, oldItems, null );
    }

    public DataSourceChangedEventArgs( IEnumerable<ItemChangedDescription> itemsChanged )
    {
      if( itemsChanged == null )
        throw new ArgumentNullException( "itemsChanged" );

      this.Initialize( DataSourceChangedAction.ItemChanged, null, null, itemsChanged );
    }

    #endregion

    #region Action Property

    public DataSourceChangedAction Action
    {
      get;
      private set;
    }

    #endregion

    #region NewItems Property

    public IList<object> NewItems
    {
      get
      {
        return m_newItems;
      }
    }

    private ReadOnlyCollection<object> m_newItems; //null

    private void SetNewItems( IEnumerable<object> items )
    {
      List<object> newItems = ( items != null )
                                ? new List<object>( items )
                                : new List<object>( 0 );

      m_newItems = new ReadOnlyCollection<object>( newItems );
    }

    #endregion

    #region OldItems Property

    public IList<object> OldItems
    {
      get
      {
        return m_oldItems;
      }
    }

    private ReadOnlyCollection<object> m_oldItems; //null

    private void SetOldItems( IEnumerable<object> items )
    {
      List<object> oldItems = ( items != null )
                                ? new List<object>( items )
                                : new List<object>( 0 );

      m_oldItems = new ReadOnlyCollection<object>( oldItems );
    }

    #endregion

    #region ItemsChanged Property

    public IList<ItemChangedDescription> ItemsChanged
    {
      get
      {
        return m_itemsChanged;
      }
    }

    private ReadOnlyCollection<ItemChangedDescription> m_itemsChanged; //null

    private void SetItemsChanged( IEnumerable<ItemChangedDescription> items )
    {
      List<ItemChangedDescription> itemsChanged = ( items != null )
                                                    ? new List<ItemChangedDescription>( items )
                                                    : new List<ItemChangedDescription>( 0 );

      m_itemsChanged = new ReadOnlyCollection<ItemChangedDescription>( itemsChanged );
    }

    #endregion

    private void Initialize( 
      DataSourceChangedAction action,
      IEnumerable<object> newItems,
      IEnumerable<object> oldItems,
      IEnumerable<ItemChangedDescription> itemsChanged )
    {
      this.Action = action;

      this.SetNewItems( newItems );
      this.SetOldItems( oldItems );
      this.SetItemsChanged( itemsChanged );
    }
  }
}
